﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PloobsEngine.SceneControl;
using PloobsEngine.Physics;
using PloobsEngine;
using PloobsEngine.Cameras;
using PloobsEngine.Input;
using Microsoft.Xna.Framework;
using PloobsEngine.Physics.Bepu;
using PloobsEngine.Modelo;
using PloobsEngine.Material;
using Microsoft.Xna.Framework.Graphics;
using PloobsEngine.Utils;
using PloobsEngine.Features;
using PloobsEngine.Commands;
using PloobsEngineDemo3;
using PloobsEngine.Light;
using Etapa1.ComercioEspacial;
using System.Windows.Forms;
using Etapa1.Pedestrian;
using Bnoerj.AI.Steering;
using PloobsEngine.Draw;

namespace Etapa1.Screens
{
    public class ComercioEspacialScreen : SceneScreen
    {
        private BepuPhysicWorld physicWorld;
        private BrutalForceWorld mundo;
        private EngineStuff engine;        
        CameraFirstPerson cam;
        public static List<SphericalObstacle> obstacles = new List<SphericalObstacle>();        
        List<Planeta> planetList = new List<Planeta>();
        List<Nave> naveList = new List<Nave>();
        NaveVeiculoPlugIn nplugin;
        PDA pda;
        Agente player1;

        public ComercioEspacialScreen(EngineStuff es)
        {
            this.engine = es;
            physicWorld = new BepuPhysicWorld();
            mundo = new BrutalForceWorld(physicWorld);                                
        }
        
        public override void LoadContent(EngineStuff es)
        {
            InputAdvanced inp = new InputAdvanced(engine);
            engine.AddComponent(inp);

            base.LoadContent(es);

            #region Models

            pda = new PDA(this);
            player1 = new Agente();
            player1.dinheiro = 500;


            ///Loader dos Planetas
            {
                planetList = XmlContentLoader.LoadXmlContent("planetas.xml", planetList.GetType()) as List<Planeta>;
                foreach (var item in planetList)
                {
                    mundo.AddObject(item.init());             
                    pda.planetas.Add(item);
                }
            } 

            ///Lista de Naves
            nplugin = new NaveVeiculoPlugIn(mundo, engine);
            nplugin.Open();
            {
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\cubo", "..\\Content\\Textures\\blue");
                sm.LoadModelo();
                BoxObject pi = new BoxObject(new Vector3(45, 0, 0), 1, new Vector3(5));
                CustomDeferred shader = new CustomDeferred(false, false, false, false);
                shader.SpecularIntensity = 0;
                shader.SpecularPower = 0;
                shader.Initialize();
                IMaterial mat = new Material(shader, MaterialType.DEFERRED);
                SteerObject  obj3 = new SteerObject(mat, pi, sm);
                mundo.AddObject(obj3);

                Nave nave = new Nave(obj3,planetList);
                nave.Nome = "SputXV";
                nave.PlanetaNoLocal = planetList.First((x) => x.NomeSistema.ToUpper() == "WASP");
                nave.dono = player1;
                nave.velocidade = 100;
                nave.rotaAtiva = null;
                nave.estoque = 5000;                

                nplugin.AddAgente(obj3);
                
            }

            {
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\cubo");
                sm.LoadModelo();
                sm.SetTexture(TextureCreator.CreateColorTexture(512, Color.Yellow),TextureType.DIFFUSE);

                BoxObject pi = new BoxObject(new Vector3(0, 50, 0), 1, new Vector3(5));
                NormalDeferred shader = new NormalDeferred();                
                shader.Initialize();
                IMaterial mat = new Material(shader, MaterialType.DEFERRED);
                SteerObject obj3 = new SteerObject(mat, pi, sm);
                mundo.AddObject(obj3);

                Nave nave = new Nave(obj3,planetList);
                nave.Nome = "Apollo34";
                nave.PlanetaNoLocal = planetList.First((x) => x.NomeSistema.ToUpper() == "WASP");
                nave.dono = player1;
                nave.velocidade = 100;
                nave.rotaAtiva = null;
                nave.estoque = 5000;

                nplugin.AddAgente(obj3);

            }


            #endregion

            cam = new CameraFirstPerson(true);
            cam.FarPlane = 5000;

            #region NormalLight
            DirectionalLight ld1 = new DirectionalLight(Vector3.Left, Color.White);
            DirectionalLight ld2 = new DirectionalLight(Vector3.Right, Color.White);
            DirectionalLight ld3 = new DirectionalLight(Vector3.Backward, Color.White);
            DirectionalLight ld4 = new DirectionalLight(Vector3.Forward, Color.White);
            DirectionalLight ld5 = new DirectionalLight(Vector3.Down, Color.White);
            float li = 0.4f;
            ld1.LightIntensity = li;
            ld2.LightIntensity = li;
            ld3.LightIntensity = li;
            ld4.LightIntensity = li;
            ld5.LightIntensity = li;
            mundo.AddLight(ld1);
            mundo.AddLight(ld2);
            mundo.AddLight(ld3);
            mundo.AddLight(ld4);
            mundo.AddLight(ld5);
            #endregion

            ////Criacao de uma Tecnica
            DeferredRenderTechnic dr = new DeferredRenderTechnic(engine);

            IRenderTechnic[] rt = new IRenderTechnic[] { dr };
            this.RenderTechnics = rt;
            mundo.AddCamera(cam);
            this.World = mundo;

            Picking pk = new Picking();
            pk.PickingRayDistance = 5000;
            engine.AddComponent(pk);

            PickingParameters pp = new PickingParameters(cam, mundo, PloobsEngine.Input.MouseButtons.RightButton);
            pp.Method = SegmentInterceptMethod.ALL;            
            PickingRedirectorCallbackObserver prc = new PickingRedirectorCallbackObserver();
            prc.redirectPicking += new RedirectPicking(prc_redirectPicking);
            pp.Observers.Add(prc);
            CommandProcessor.getCommandProcessor().SendCommandSyncronous(pp);

            {
                InputPlayableKeyBoard ip1 = new SimpleConcreteKeyboardInputPlayable(StateKey.PRESS, Microsoft.Xna.Framework.Input.Keys.Space, changeCameraMode, EntityType.TOOLS);
                BindKeyCommand mm = new BindKeyCommand(ip1, BindAction.ADD);
                CommandProcessor.getCommandProcessor().SendCommandSyncronous(mm, InputAdvanced.MyName);
            }
            {
                InputPlayableKeyBoard ip1 = new SimpleConcreteKeyboardInputPlayable(StateKey.PRESS, Microsoft.Xna.Framework.Input.Keys.Enter, PDACONSOLE, EntityType.TOOLS);
                BindKeyCommand mm = new BindKeyCommand(ip1, BindAction.ADD);
                CommandProcessor.getCommandProcessor().SendCommandSyncronous(mm, InputAdvanced.MyName);
            }

        }

        bool enabled = true;
        public void changeCameraMode(InputPlayableKeyBoard ipk)
        {
            enabled = !enabled;
            cam.EnableMouse(enabled);            
        }

        public void PDACONSOLE(InputPlayableKeyBoard ipk)
        {
            if (enabled == true)
            {
                enabled = !enabled;
                cam.EnableMouse(enabled);
            }

            PDAForm f = new PDAForm(pda);
            f.ShowDialog();
        }

        RayTestInfo ri = null;
        void prc_redirectPicking(object obj)
        {
            ri = obj as RayTestInfo;
            if (ri.Object is IObject)
            {

                if (ri.Object.Agente is Planeta)
                {
                    PlanetaForm pf = new PlanetaForm(ri.Object.Agente as Planeta);
                    pf.ShowDialog();
                }
                else if (ri.Object.Agente is Nave)
                {
                    NaveForm nf = new NaveForm(ri.Object.Agente as Nave, planetList);
                    nf.ShowDialog();
                }
            }            
        }


        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            obstacles.Clear();
            foreach (var item in planetList)
            {
                //obstacles.Add( new SphereObject(item.Obj.Position, item.Obj.Modelo.GetBoudingSphere().Radius * item.Obj.PhysicObject.Scale.X));
            }

            Drawing.Draw2dTextAt2dLocation("DINHEIRO " + player1.dinheiro,new Vector2(10,10),Color.White);

            obstacles.Clear();
            foreach (var item in planetList)
            {
               obstacles.Add(new SphericalObstacle(item.Obj.PhysicObject.Scale.X,item.Obj.Position));
            }

            nplugin.Update(EngineStuff.Clock.TotalSimulationTime, EngineStuff.Clock.ElapsedSimulationTime);
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }


    }
}

